﻿using System;
using System.Collections.Generic;
using JTLeigh.Commerce.Spencer.Features.ProductFeedback.Business.Caches;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ProductFeedbackE = JTLeigh.Commerce.Spencer.Features.ProductFeedback.Common.Entities.ProductFeedback;

namespace JTLeigh.Commerce.Spencer.Features.ProductFeedback.Business.UnitTests.Caches
{

	/// <summary>
	/// Unit tests for the <see cref="InMemoryProductFeedbackCache"/> class.
	/// </summary>
	[TestClass]
	public class InMemoryProductFeedbackCacheFixture
	{

		#region Fields

		private static Guid TestTenant1Id = Guid.NewGuid();
		private static Guid TestTenant2Id = Guid.NewGuid();
        private const string TestCatalogId = "BaseCatalog";
        private const string TestProduct1Id = "123";
		private const string TestProduct2Id = "456";

		#endregion // Fields

		#region Methods

		#region ProductFeedback

		/// <summary>
		/// Ensures <see cref="InMemoryProductFeedbackCache.GetProductFeedback"/> and
		/// <see cref="InMemoryProductFeedbackCache.SetProductFeedback"/> get and set feedback in 
		/// the cache as expected for multiple products for a single tenant.
		/// </summary>
		/// <remarks>
		/// <para>
		/// This test uses two different product identifiers in the same tenant.
		/// </para>
		/// </remarks>
		[TestMethod]
		public void TestGetSetProductFeedbackSingleTenant()
		{
			InMemoryProductFeedbackCache cache;
			Dictionary<Guid, ProductFeedbackE> feedback1;
			Dictionary<Guid, ProductFeedbackE> feedback2;

			cache = new InMemoryProductFeedbackCache();
			Assert.IsNull(cache.GetProductFeedback(TestTenant1Id, TestCatalogId, TestProduct1Id));
			Assert.IsNull(cache.GetProductFeedback(TestTenant1Id, TestCatalogId, TestProduct2Id));

			feedback1 = new Dictionary<Guid, ProductFeedbackE>();
			feedback1.Add(Guid.NewGuid(), new ProductFeedbackE());
			feedback1.Add(Guid.NewGuid(), new ProductFeedbackE());
			feedback1.Add(Guid.NewGuid(), new ProductFeedbackE());
			cache.SetProductFeedback(TestTenant1Id, TestCatalogId, TestProduct1Id, feedback1);
			feedback2 = new Dictionary<Guid, ProductFeedbackE>();
			feedback2.Add(Guid.NewGuid(), new ProductFeedbackE());
			feedback2.Add(Guid.NewGuid(), new ProductFeedbackE());
			feedback2.Add(Guid.NewGuid(), new ProductFeedbackE());
			cache.SetProductFeedback(TestTenant1Id, TestCatalogId, TestProduct2Id, feedback2);
			Assert.AreSame(feedback1, cache.GetProductFeedback(TestTenant1Id, TestCatalogId, TestProduct1Id));
			Assert.AreSame(feedback2, cache.GetProductFeedback(TestTenant1Id, TestCatalogId, TestProduct2Id));
		}

		/// <summary>
		/// Ensures <see cref="InMemoryProductFeedbackCache.GetProductFeedback"/> and
		/// <see cref="InMemoryProductFeedbackCache.SetProductFeedback"/> get and set feedback in 
		/// the cache as expected for a single product for multiple tenants.
		/// </summary>
		/// <remarks>
		/// <para>
		/// This test uses the same product identifier in two different tenants, ensuring 
		/// isolation between tenant cache partitions.
		/// </para>
		/// </remarks>
		[TestMethod]
		public void TestGetSetProductFeedbackMultipleTenants()
		{
			InMemoryProductFeedbackCache cache;
			Dictionary<Guid, ProductFeedbackE> feedback1;
			Dictionary<Guid, ProductFeedbackE> feedback2;

			cache = new InMemoryProductFeedbackCache();
			Assert.IsNull(cache.GetProductFeedback(TestTenant1Id, TestCatalogId, TestProduct1Id));
			Assert.IsNull(cache.GetProductFeedback(TestTenant2Id, TestCatalogId, TestProduct1Id));

			feedback1 = new Dictionary<Guid, ProductFeedbackE>();
			feedback1.Add(Guid.NewGuid(), new ProductFeedbackE());
			feedback1.Add(Guid.NewGuid(), new ProductFeedbackE());
			feedback1.Add(Guid.NewGuid(), new ProductFeedbackE());
			cache.SetProductFeedback(TestTenant1Id, TestCatalogId, TestProduct1Id, feedback1);
			feedback2 = new Dictionary<Guid, ProductFeedbackE>();
			feedback2.Add(Guid.NewGuid(), new ProductFeedbackE());
			feedback2.Add(Guid.NewGuid(), new ProductFeedbackE());
			feedback2.Add(Guid.NewGuid(), new ProductFeedbackE());
			cache.SetProductFeedback(TestTenant2Id, TestCatalogId, TestProduct1Id, feedback2);
			Assert.AreSame(feedback1, cache.GetProductFeedback(TestTenant1Id, TestCatalogId, TestProduct1Id));
			Assert.AreSame(feedback2, cache.GetProductFeedback(TestTenant2Id, TestCatalogId, TestProduct1Id));
		}

		#endregion // ProductFeedback

		#endregion // Methods

	}

}
